/*
 * BaseAction.java
 * 
 * Version information
 * 
 * Mar 16, 2006
 * 
 * Copyright (c) AmSoft Systems, 2006
 */

package net.amsoft.iservice.icontact.webapp.struts.action;

import java.util.ArrayList;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.amsoft.iservice.icontact.hibernate.ContactPage;
import net.amsoft.iservice.icontact.hibernate.Message;
import net.amsoft.iservice.icontact.hibernate.dataObject.IBrokerData;
import net.amsoft.iservice.icontact.hibernate.dataObject.LoginData;
import net.amsoft.iservice.icontact.service.IContact;
import net.amsoft.iservice.icontact.util.IContactConstants;
import net.amsoft.iservice.util.EmailService;
import static net.amsoft.iservice.util.IServiceConstants.*;
import net.amsoft.iservice.util.exception.IServiceException;

import org.apache.log4j.Logger;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

/**
 * An action class that extends struts action class and defines default
 * actions for the application.
 * 
 * @author rahul
 * 
 */
public abstract class BaseAction extends Action {
	private static Logger oLogger = Logger.getLogger(BaseAction.class);

	public final ActionForward execute(ActionMapping oMapping,
			ActionForm oForm, HttpServletRequest oRequest,
			HttpServletResponse oResponse) {
		oLogger.info("execute() : entry");
		preProcess(oMapping, oForm, oRequest, oResponse);
		ActionMessages oMsgs = new ActionErrors();
		try {
			return process(oMapping, oForm, oRequest, oResponse);
		} catch (Exception e) {
			if (e instanceof IServiceException) {
				IServiceException oISE = (IServiceException) e;
				oMsgs.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(oISE
						.getMessage(), false));
				saveErrors(oRequest, oMsgs);
				oLogger.error("execute() : Exception, ErrorCode: "
						+ oISE.getErrorCode() + ", Message: "
						+ oISE.getMessage());
			} else {
				oLogger.error("execute() : Exception: Message: "
						+ e.getMessage());
			}
			return oMapping.findForward(IContactConstants.FWD_CHKLOGIN);
		} finally {
			postProcess(oMapping, oForm, oRequest, oResponse);
		}
	}

	public void preProcess(ActionMapping oMapping, ActionForm oForm,
			HttpServletRequest oRequest, HttpServletResponse oResponse) {

		oLogger.info("preProcess(): entry");
		try {
			// get the existing session
			HttpSession ohSession = oRequest.getSession(false);
			Object oLoginData = ohSession
					.getAttribute(IContactConstants.SESSION_LOGIN_OBJ);

			if (oLoginData == null) {
				oLoginData = new LoginData();
				ohSession.setAttribute(IContactConstants.SESSION_LOGIN_OBJ,
						oLoginData);

				oLogger.debug("preProcess(): new LoginData created");
			}
			Object oIBrokerData = ohSession
					.getAttribute(IContactConstants.SESSION_IBROKER_OBJ);
			if (oIBrokerData == null) {
				oIBrokerData = new IBrokerData();
				loadIBrokerData((IBrokerData) oIBrokerData, oRequest
						.getServerName());
				ohSession.setAttribute(IContactConstants.SESSION_IBROKER_OBJ,
						oIBrokerData);
				oLogger.debug("preProcess(): new IBrokerData created");
			}
		} catch (Throwable ex) {
			oLogger.fatal("preProcess(): Exception: " + ex.getMessage());
		}
		oLogger.info("preProcess(): " + "exit");
	}// preProcess() ends

	/**
	 * Used to send the notification e-mail to the i-name, the notification is
	 * about recieving a new contact reequest
	 * 
	 * @param oMessage
	 *            Message sent by the sender which is saved to database
	 * @param oRequest
	 *            Http request
	 * @throws IServiceException
	 */
	protected void sendNotificationEmail(Message oMessage,
			HttpServletRequest oRequest) throws IServiceException {
		oLogger.info("sendNotificationEmail() : entry");
		ContactPage oCPage = oMessage.getSynonym().getContactPage();
		String sSubject = prepareNtfSub(oCPage.getNotificationEmailSub(),
				oRequest, oMessage);
		String sMsg = prepareNtfMsg(oCPage, oMessage, oRequest);
		String sFromAddr = "noreply@" + oRequest.getServerName();
		String sReplyToAddr = oMessage.getSenderEMail();
		EmailService oEmail = new EmailService();
		oEmail.setBody(sMsg);
		oEmail.setFromAddress(sFromAddr);
		oEmail.setReplyToAddress(sReplyToAddr);
		oEmail.setReceipientList(new ArrayList(oCPage.getEmail()));
		oEmail.setSubject(sSubject);
		oEmail.debug("Sending Notification Email");
		oEmail.sendMail();
		oLogger.info("sendNotificationEmail(): " + "exit");
	}

	public abstract ActionForward process(ActionMapping oMapping,
			ActionForm oForm, HttpServletRequest oRequest,
			HttpServletResponse oResponse) throws Exception;

	public void postProcess(ActionMapping oMapping, ActionForm oForm,
			HttpServletRequest oRequest, HttpServletResponse oResponse) {
	}

	/**
	 * Used to create the subject of the notifiation e-mail to be sent to the
	 * i-name.
	 * 
	 * @param sub
	 *            Notification email subject stored in contact page
	 *            configuration
	 * @param oRequest
	 *            Current Http request
	 * @param oMessage
	 *            Message sent by the sender
	 * @return Subject of the e-mail
	 */
	private String prepareNtfSub(String sub, HttpServletRequest oRequest,
			Message oMessage) {
		oLogger.info("prepareNtfSub() : entry");
		if (sub == null || sub.trim().length() == 0) {
			String sSender = oMessage.getSenderName();
			if (oMessage.getSenderIName() != null
					&& oMessage.getSenderIName().length() > 0) {
				sSender = oMessage.getSenderIName();
			}
			sub = getResources(oRequest).getMessage(oRequest.getLocale(),
					IContactConstants.MSG_DEF_NOT_EMAIL_SUB, sSender);
		}
		oLogger.info("prepareNtfSub(): exit, Return NtfSub=" + sub);
		return sub;
	}

	/**
	 * Used to create the message body of the notifiation e-mail to be sent to
	 * the i-name.
	 * 
	 * @param cPage
	 *            Contact page configured
	 * @param oMessage
	 *            Message sent by the sender
	 * @param oRequest
	 *            Current Http request
	 * @return Email message text
	 */
	private String prepareNtfMsg(ContactPage cPage, Message oMessage,
			HttpServletRequest oRequest) {
		oLogger.info("prepareNtfMsg() : entry");
		String customMsg = cPage.getNotificationEmailMsg();
		if (customMsg == null) {
			customMsg = "";
		}
		Object[] params = { oMessage.getSynonym().getName(),
				oMessage.getSenderName(), oMessage.getSenderIName(),
				oMessage.getSenderEMail(), oMessage.getText(), customMsg,
				oRequest.getServerName() };
		String sCompleteMsg = getResources(oRequest).getMessage(
				oRequest.getLocale(), IContactConstants.MSG_DEF_NOT_EMAIL_MSG,
				params);
		oLogger.info("prepareNtfMsg(): exit, return NtfMsg=" + sCompleteMsg);
		return sCompleteMsg;
	}

	/**
	 * Used to load the ibroker data
	 * 
	 * @param oIBData
	 *            IBroker object
	 * @param ibrokerName
	 *            Name of the ibroker
	 * @return
	 */
	private Map loadIBrokerData(IBrokerData oIBData, String ibrokerName) {
		oLogger.info("loadIBrokerData() : entry");
		Map oIBMap = null;
		try {
			oIBMap = IContact.getIBrokerData(ibrokerName);
			if (oIBMap.keySet().contains(IB_BANNER_KEY)) {
				oIBData.setBannerLink((String) oIBMap.get(IB_BANNER_KEY));
				oIBMap.remove(IB_BANNER_KEY);
			}
		} catch (Exception e) {
			oLogger.error("loadIBrokerData(): Exception=" + e.getMessage());
		}
		oIBData.setIBrokerMap(oIBMap);
		oLogger.info("loadIBrokerData(): exit, return IBMap=" + oIBMap);
		return oIBMap;
	}
}
